iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Mobile Development

Spring Boot+Android 30天 實戰開發 系列 第 10

【Day - 10】更簡潔的數據驗證 - Spring Validation (下)

  • 分享至 

  • xImage
  •  

4. 自訂義驗證器

在Spring Boot應用程式中,有時你可能需要創建自定義的驗證規則來滿足特定的業務需求。Spring Validation提供了一個強大的機制,允許你創建自定義的驗證器來執行這些規則。本節將介紹如何創建和整合自定義驗證註解。

4.1 範例:驗證手機號碼

Spring Validation並未提供手機號碼的驗證註解,因此本範例將演示如何自定義一個註解,用於驗證台灣的手機號碼。

(1) 創建自定義驗證註解

首先,創建一個自定義註解 @ValidPhoneNumber

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneNumberValidator.class)
public @interface ValidPhoneNumber {
    String message() default "Invalid phone number";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
  • 程式碼講解補充:
    • 第3行:這個元注解指定了用於執行驗證的驗證器類。在這裡,我們將它設置為 PhoneNumberValidator.class,這意味著當使用 @ValidPhoneNumberA 註解時,會調用 PhoneNumberValidator 類來執行驗證邏輯。
    • 第6行:這是驗證失敗時顯示的默認消息。如果驗證失敗,將會使用這個消息作為錯誤消息。

(2) 創建驗證器類

創建一個驗證器 PhoneNumberValidator,用於執行驗證邏輯:

public class PhoneNumberValidator implements ConstraintValidator<ValidPhoneNumber, String> {

    @Override
    public void initialize(ValidPhoneNumber constraintAnnotation) {
    }

    @Override
    public boolean isValid(String phoneNumber, ConstraintValidatorContext context) {
        if (phoneNumber == null) {
            return false;
        }

        // 定義規則:手機號碼必須以09開頭,總共10位數字
        return phoneNumber.matches("^09\\d{8}$");
    }
}

(3) 創建要驗證的實體類

要在實體類中使用自定義手機號碼驗證規則,只需將我們剛才自定義註解 @ValidPhoneNumber 應用到手機號碼屬性上。如下:

public class UserProfile {
    @ValidPhoneNumber
    private String phoneNumber;

    // 其他屬性和方法
}

(4) 在控制器中使用驗證器

最後,在你的控制器中使用自定義驗證器,透過@Valid 註解來觸發驗證。

@RestController
@RequestMapping("/api")
public class UserProfileController {

    @PostMapping("/user-profile")
    public ResponseEntity<String> createUserProfile(@RequestBody @Valid UserProfileRequest request, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            // 紀錄驗證錯誤
            List<String> errorMessages = new ArrayList<>();

            // 提取所有驗證錯誤的消息
            for (FieldError error : bindingResult.getFieldErrors()) {
                errorMessages.add(error.getDefaultMessage());
            }

            // 返回錯誤消息給给客戶端
            return ResponseEntity.badRequest().body("Validation failed: " + String.join(", ", errorMessages));
        }

        // 驗證通過,執行保存用戶操作...
        return ResponseEntity.ok("UserProfile created successfully");
    }
}

(5) 使用Postman發送請求

  • 驗證通過:輸入正確格式的手機號碼
    圖片無法顯示
  • 驗證失敗:輸入超過10位數字的號碼
    圖片無法顯示

5. 分組驗證

在 Spring Validation 中,分組驗證是一種強大的技巧,它允許您根據不同的使用情境對同一個實體類的屬性進行差異化的數據驗證。這節將介紹 Spring Validation 中分組驗證的基本概念以及如何使用它來提高數據驗證的靈活性。

5.1 什麼是分組驗證?

分組驗證通常在以下情境中大有作為:您可能希望對同一個實體類的不同屬性在不同的場景下進行驗證。例如,在使用者註冊過程中,您可能需要驗證使用者名稱、密碼等屬性,但在使用者資料更新時,僅需要驗證電子郵件地址和手機號碼的格式。這正是分組驗證的用武之地。

分組驗證允許您將驗證規則分為不同的組別,然後根據需要選擇性地驗證某個組別的規則。這使得數據驗證變得更加靈活,可應用於不同的業務操作。

5.2 在Spring Validation中使用分組驗證

要在Spring Validation中使用分組驗證,你需要執行以下步驟:

(1) 定義驗證分組

首先,你需要在你的實體類中定義驗證分組。這可以通過在驗證註解上使用 groups 屬性來實現。例如:

public class UserProfile {
    @NotBlank(groups = {Registration.class, Update.class})
    @Size(min = 2, max = 10)
    private String username;
    
    @NotBlank(groups = {Registration.class})
    private String password;
    
    @Email(groups = {Registration.class, Update.class})
    private String email;
    
    //使用第4小節所學的自定義驗證註解
    @ValidPhoneNumbergroups = {Registration.class, Update.class}  
    private String phoneNumber;
    
    // 定義驗證分組
    public interface Registration {}
    public interface Update {}
}

在上述範例中,我們定義了兩個驗證分組:RegistrationUpdate。不同的屬性根據需要被分配到這些組中。

對於 Registration.classUpdate.class 這兩個分組,您需要自己在程式碼中創建它們。這些分組通常是 Java 中的 interface,且接口不需要定義任何方法,它只是用於標識相關的驗證分組,您可以在任何合適的包(package)中創建它們。

步驟二:在控制器中應用驗證分組

接下來,在你的控制器中,你可以通過在方法參數上使用@Validated 註解並指定要使用的分組來應用驗證分組。例如:

@RestController
@RequestMapping("/user")
public class UserController {
    @PostMapping("/register")
    public ResponseEntity<String> registerUser(@Validated(UserProfileRequest.Registration.class) @RequestBody UserProfileRequest userProfile) {
        // 執行使用者註冊操作...
        return ResponseEntity.ok("User registered successfully");
    }

    @PutMapping("/update")
    public ResponseEntity<String> updateUser(@Validated(UserProfileRequest.Update.class) @RequestBody UserProfileRequest userProfile) {
        // 執行使用者更新操作...
        return ResponseEntity.ok("User updated successfully");
    }
}

通過使用分組驗證,您可以更好地控制哪些屬性需要在不同的業務場景中進行驗證,從而提高了驗證的精確性和可維護性。這對於複雜的應用程式來說尤其有用。

6. 異常處理與錯誤訊息

在使用 Spring Validation 進行參數驗證時,當驗證失敗時,Spring Validation 會拋出 MethodArgumentNotValidException 異常。在本節中,我們將解釋如何處理這些異常以及如何自定義錯誤訊息,以提供更友善的使用者回饋。

6.1 異常處理

當參數驗證失敗時,Spring Validation 會拋出 MethodArgumentNotValidException 異常。要捕獲和處理這些異常,你可以在控制器方法中使用 @ExceptionHandler 註解來定義異常處理程式。

以下是一個範例,演示如何在 Spring Boot 應用程式中捕獲數據驗證異常:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> handleValidationException(MethodArgumentNotValidException ex) {
        return ResponseEntity.badRequest().body("參數驗證失敗:" + ex.getBindingResult().getFieldError().getDefaultMessage());
    }
}

在上面的範例中,我們創建了一個全局異常處理程式 GlobalExceptionHandler,並使用 @ExceptionHandler 註解定義了一個處理 MethodArgumentNotValidException 異常的方法。當參數驗證失敗時,此方法會返回一個自定義的錯誤訊息。

6.2 自訂錯誤訊息

Spring Validation 允許你自訂錯誤訊息,以提供更友善的使用者回饋。你可以在驗證註解上使用 message 屬性,來指定錯誤訊息。在錯誤訊息中,你可以使用佔位符來參考驗證失敗的欄位和其他資訊。

public class Product {

    @NotBlank(message = "產品名稱不能為空")
    private String name;

    @Positive(message = "價格必須是正數")
    private double price;

    // 省略其他屬性和方法
}

在上面的範例中,我們在 @NotBlank 註解中自訂了錯誤訊息 "產品名稱不能為空",在 @Positive 註解中自訂了錯誤訊息 "價格必須是正數"。當參數驗證失敗時,將顯示這些自訂錯誤訊息。

自訂錯誤訊息可以協助提升使用者體驗,讓使用者更容易理解和解決問題。

透過異常處理和自訂錯誤訊息,你可以更好地處理參數驗證失敗的情況,並為使用者提供有用的回饋資訊,從而改善應用程式的品質和可用性。

7. 總結

在本篇中,我們深入探討了 Spring Validation 在 Spring Boot 應用程式中的應用,強調了數據驗證對於應用程式的穩健性和安全性的重要性。我們總結了以下關鍵知識點:

  • 我們介紹了 Spring Validation 的基本概念和作用,它可以用於驗證請求參數和數據模型的有效性,幫助預防無效數據的輸入和處理。
  • 我們學習了 Spring Validation 常用的註解,包括空值檢查、數值檢查、字串格式驗證等,這些註解可以幫助我們定義驗證規則。
  • 我們了解了如何在 Spring Boot 中整合 Spring Validation,包括添加依賴、配置驗證器和處理驗證結果。
  • 我們探討了自定義驗證規則的方法,演示了如何創建自定義驗證器並將其整合到 Spring Boot 應用程式中,以滿足特定的驗證需求。
  • 我們介紹了分組驗證的概念,示範了如何根據不同的驗證場景對參數進行驗證,以實現更精細化的數據驗證。
  • 最後,我們討論了異常處理與錯誤消息的重要性,演示了如何捕獲驗證異常並提供友好的錯誤消息,以改善使用者體驗。

總的來說,數據驗證是確保應用程式品質和安全性的關鍵步驟之一。我們鼓勵讀者積極採用和實踐數據驗證技術,以提高數據品質和安全性,確保應用程式的穩健性和可用性。通過合理的數據驗證,可以有效減少無效數據帶來的問題,提高使用者滿意度,確保應用程式的可靠性。


上一篇
【Day - 09】更簡潔的數據驗證 - Spring Validation (上)
下一篇
【Day - 11】使用 Docker Compose 管理團隊開發環境 (上)
系列文
Spring Boot+Android 30天 實戰開發 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言